package com.huarui.partner.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.ewaf.framework.model.IDataObject;
import org.ewaf.framework.model.ListModel;
import org.ewaf.framework.service.BaseService;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import com.huarui.company.dao.ICompanyDao;
import com.huarui.company.model.Company;
import com.huarui.dictionary.service.DictionaryReadOnlyService;
import com.huarui.notice.INoticeService;
import com.huarui.notice.Notice;
import com.huarui.partner.dao.IPartnerAddressDao;
import com.huarui.partner.dao.IPartnerDao;
import com.huarui.partner.dao.impl.PartnerAddressDaoImpl;
import com.huarui.partner.model.Partner;
import com.huarui.partner.model.PartnerAddress;
import com.huarui.partner.model.PartnerListModel;
import com.huarui.user.model.SessionMessage;
import com.huarui.user.security.UserHolder;
import com.huarui.util.PinyinToolkit;
/**
 * xzz
 * @author Administrator
 *
 */
public class PartnerService extends BaseService {
	
	@SuppressWarnings("unused")
	private Logger logger = Logger.getLogger(PartnerService.class);
	
	@SuppressWarnings("unused")
	private DictionaryReadOnlyService dictionaryReadOnlyService;

	private IPartnerAddressDao partnerAddressDao;
	
	private ICompanyDao companyDao;
	
	private INoticeService noticeService;
	
	public void setNoticeService(INoticeService noticeService) {
		this.noticeService = noticeService;
	}

	public void setPartnerAddressDao(PartnerAddressDaoImpl partnerAddressDao) {
		this.partnerAddressDao = partnerAddressDao;
	}

	public void setDictionaryReadOnlyService(
			DictionaryReadOnlyService dictionaryReadOnlyService) {
		this.dictionaryReadOnlyService = dictionaryReadOnlyService;
	}

	public void setCompanyDao(ICompanyDao companyDao) {
		this.companyDao = companyDao;
	}

	private IPartnerDao getDao() {
		return (IPartnerDao) dao;
	}

	/**
	 * 创建客户资料
	 * 
	 * @param cm
	 */
	public void createPartner(Partner ptr) {
		ptr.setPyCode("pym");
		ptr.setGmtCreate(Calendar.getInstance().getTime());
		// Company owner_cp = null;
		ptr.setOwnerId(null);
		super.create(ptr);
	}

	/**
	 * 逻辑删除客户
	 * 
	 * @param c
	 */
	public void deletePartner(Partner ptr) {
		this.getDao().deletePartner(ptr);
	}

	/**
	 * 根据Id逻辑删除客户
	 * 
	 * @param id
	 */
	public void deletePartnerById(Integer id) {
		Partner ptr = (Partner) this.dao.getById(id);
		if (ptr != null) {
			deletePartner(ptr);
		}
	}

	@SuppressWarnings("unchecked")
	public List<Partner> getPartnersByLikeName(String name, ListModel model) {
		List<? extends IDataObject> cs = this.dao.query(model);
		List<Partner> css = (List<Partner>) cs;
		return css;
	}

	/**
	 * 根据名称模糊查询业务伙伴
	 * 
	 * @param name
	 * @return
	 */
	public List<Partner> getPartnersByLikeName(String name) {
		return this.getDao().getPartnersByLikeName(name);
	}

	@SuppressWarnings("unchecked")
	public ListModel<Partner> getAllPartnerByOwnerId(PartnerListModel lm, Integer ownerId) {

		
		Map map = new HashMap<String, String>();
		map.put("ownerId", ownerId);
		map.put("orderBy", lm.getOrderBy());
		map.put("name",lm.getName());
		map.put("contactor",lm.getContactor());
		map.put("pyCode",lm.getPyCode());
		map.put("relation",lm.getRelation());
		map.put("start", lm.getStart());
		map.put("pageSize", lm.getPageSize());
		map.put("isDelete",lm.getIsDelete());
		map.put("desc", lm.isDesc());
		lm.setTotal(this.getDao().countByConditions(map));
		
		List<Partner> partnerList = this.getDao().getAllPartnerByOwnerId(map);
		lm.setResult(partnerList);
		return lm;

	}

	public Partner getPartnerById(Integer id) {
		return (Partner) this.dao.getById(id);
	}

	public List<Partner> getPartnerByOwnerId(Integer ownerId) {
		return getDao().getPartnerByOwnerId(ownerId);
	}

	public Map<String, Object> getPartnerByIdAndOwnerId(String id) {
		SessionMessage se = UserHolder.getCurrentSessionMessage();
		Integer ownerId = se.getCompanyId();
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("id", id);
		paramsMap.put("ownerId", ownerId);
		return this.getDao().getByIdAndOwnerId(paramsMap);
	}
	
	
	public void createAll(final Partner partner,
			final List<PartnerAddress> partnerAddressList) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {

					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner
							.getName()));
					getDao().create(partner);

					for (PartnerAddress partnerAddress : partnerAddressList) {

						partnerAddress.setPartnerId(partner.getId());

					}

					partnerAddressDao.batchInsert(partnerAddressList);
				} catch (Exception e) {
					throw new RuntimeException(e.getMessage());
				}

				return status;
			}
		});

	}

	public void updateAllwithDelete(final Partner partner,
			final List<PartnerAddress> partnerAddressUpdateList,
			final List<PartnerAddress> partnerAddressdeleteList) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner.getName()));
					getDao().updatePartner(partner);
					partnerAddressDao.batchUpdate(partnerAddressUpdateList);
					if (partnerAddressdeleteList.size() != 0) {
						partnerAddressDao.batchDelete(partnerAddressdeleteList);
					}

				} catch (Exception e) {
					throw new RuntimeException();
				}

				return status;
			}
		});

	}

	public void updateAndSaveAllwithDelete(final Partner partner,
			final List<PartnerAddress> partnerAddressUpdateList,
			final List<PartnerAddress> partnerAddressdeleteList,
			final List<PartnerAddress> partnerAddressAddList) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner
							.getName()));
					getDao().updatePartner(partner);

					partnerAddressDao.batchUpdate(partnerAddressUpdateList);

					if (partnerAddressdeleteList.size() != 0) {

						partnerAddressDao.batchDelete(partnerAddressdeleteList);

					}
					for (PartnerAddress partnerAddress : partnerAddressAddList) {

						partnerAddress.setPartnerId(partner.getId());

					}

					partnerAddressDao.batchInsert(partnerAddressAddList);
				} catch (Exception e) {

					e.printStackTrace();
				}

				return status;
			}
		});
	}

	public void updateAll(final Partner partner,
			final List<PartnerAddress> partnerAddressdeleteList) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner
							.getName()));
					getDao().updatePartner(partner);

					if (partnerAddressdeleteList.size() != 0) {

						partnerAddressDao.batchDelete(partnerAddressdeleteList);

					}
				} catch (Exception e) {
					throw new RuntimeException();
				}

				return status;
			}
		});

	}

	public void save(final Partner partner,
			final List<PartnerAddress> partnerAddressAddList,final List<PartnerAddress> partnerAddressdeleteList) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					
					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner.getName()));
					getDao().updatePartner(partner);
					for (PartnerAddress partnerAddress : partnerAddressAddList) {
						partnerAddress.setPartnerId(partner.getId());
					}
					partnerAddressDao.batchInsert(partnerAddressAddList);
					
					if (partnerAddressdeleteList.size() != 0) {

						partnerAddressDao.batchDelete(partnerAddressdeleteList);

					}
				} catch (Exception e) {
					throw new RuntimeException();
				}

				return status;
			}
		});

	}

	public void createTogether(final Partner partner,
			final Partner partner1,final Notice notice) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					partner.setPyCode(PinyinToolkit
							.cn2FirstSpell(partner.getName()));
					partner1.setPyCode(PinyinToolkit
							.cn2FirstSpell(partner1.getName()));
					getDao().create(partner);
					getDao().create(partner1);
					noticeService.send(notice, 24);
				} catch (Exception e) {
					e.printStackTrace();
					throw new RuntimeException();
				}

				return status;
			}
		});

	}	
	
	public void updateTogether(final Partner partner,
			final Partner partner1,final Notice notice) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner
							.getName()));
					getDao().updatePartner(partner);
					partner1.setPyCode(PinyinToolkit.cn2FirstSpell(partner1
							.getName()));
					getDao().updatePartner(partner1);
					noticeService.send(notice, 24);
				} catch (Exception e) {
					e.printStackTrace();
					throw new RuntimeException();
				}

				return status;
			}
		});

	}	
	public void updatePn(final Partner partner,
			final Partner partner1,final Notice notice) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					
					partner.setPyCode(PinyinToolkit.cn2FirstSpell(partner
							.getName()));
					getDao().updatePartner(partner);
					
					partner1.setPyCode(PinyinToolkit
							.cn2FirstSpell(partner1.getName()));
					
					getDao().create(partner1);
					noticeService.send(notice, 24);
				} catch (Exception e) {
					e.printStackTrace();
					throw new RuntimeException();
				}

				return status;
			}
		});

	}	
	
	public void updatePn1(final Partner partner,
			final Partner partner1,final Notice notice) {

		transactionTemplate.execute(new TransactionCallback() {

			@Override
			public Object doInTransaction(TransactionStatus status) {

				try {
					
					partner.setPyCode(PinyinToolkit
							.cn2FirstSpell(partner.getName()));
					getDao().create(partner);
					partner1.setPyCode(PinyinToolkit.cn2FirstSpell(partner1
							.getName()));
					getDao().updatePartner(partner1);
					noticeService.send(notice, 24);
				} catch (Exception e) {
					
					throw new RuntimeException();
				}

				return status;
			}
		});

	}
	
	public Partner getPartnerByCode(String code) {

		return this.getDao().getPartnerByCode(code);

	}
	public List<Partner> getPartnerByIdent(Map map){
		
		
		return this.getDao().getPartnerByIdent(map);
		
	}

	public Partner getPartnerByTaxCode(Map map){
		
		return this.getDao().getPartnerByTaxCode(map);
	}

	@SuppressWarnings("unchecked")
	public List<Partner> getPartnerByOwnerIdaAndLikeName(Integer ownerId,String name) {
		Map map = new HashMap();
		map.put("ownerId", ownerId);
		map.put("name", name);
		return getDao().getPartnerByOwnerIdaAndLikeName(map);

	}

	@SuppressWarnings("unchecked")
	public ListModel getPartnersByPaging(ListModel listModel,SessionMessage sessionMessage, Map map) {
		int total = getDao().getCountByConditions(map);
		listModel.setTotal(total);
		map.put("listModel", listModel);
		listModel.setResult(getDao().getPartnersByConditions(map));
		return listModel;
	}

    /**
     * 
     * @param partnerlistModel
     * @param queryParam
     * @param relations
     * @author jiwei.yi
     */
	@SuppressWarnings("unchecked")
	public ListModel<Partner> getPartnersByPagingCondition(ListModel<Partner> partnerlistModel, String queryParam,String type,String qualify) {
		SessionMessage sessionMessage = UserHolder.getCurrentSessionMessage();
		Map<String, Object> queryMap = new HashMap<String, Object>();				
		if (queryParam != null) {			
			int index = StringUtils.indexOf(StringUtils.strip(queryParam), "{");
			if (index == -1) {
				queryMap.put("condition", queryParam);
			} else {
				queryMap = (Map<String, Object>) JSONObject.toBean(JSONObject.fromObject(queryParam), Map.class);
			}
		}
		List<String> relations = new ArrayList<String>();		
		relations.add(Partner.REALATION_BOTH);
    	if(type.equals(Partner.REALATION_CUSTOMER)){
    		relations.add(Partner.REALATION_CUSTOMER);
    	}else if(type.equals(Partner.REALATION_SUPPLY)){
    		relations.add(Partner.REALATION_SUPPLY);
    	}
    	if(StringUtils.isNotBlank(qualify)){
    		queryMap.put("qualify", Integer.valueOf(qualify));
    	}
		queryMap.put("ownerId", sessionMessage.getCompanyId());		
		queryMap.put("relation", relations);
		queryMap.put("isDelete", 0);
		return this.getPartnersByPaging(partnerlistModel, sessionMessage,queryMap);
	}
	public Partner getComboProperties(Partner partner){
		Partner ret=new Partner();
		ret.setId(partner.getId());
		ret.setName(partner.getName());
		ret.setPyCode(partner.getPyCode());
		return ret;
	}
	
	public Partner findPartnerByOwnerId(Map map){
		return this.getDao().findPartnerByOwnerId(map);
	}
	
	/**
	 * 根据公司ID和本公司ID查找
	 * 
	 * @author ycf
	 * 
	 * @param compId
	 * @return
	 */
	private List<Partner> getPartnerByCompIdAndOwnerId(Integer compId) {
		SessionMessage se = UserHolder.getCurrentSessionMessage();
		Integer ownerId = se.getCompanyId();
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("companyId", compId);
		map.put("ownerId", ownerId);
		map.put("isDelete", 0);
		map.put("relation", Partner.REALATION_SUPPLY);
		
		List<Partner> list = new ArrayList<Partner>();
		Partner partner = this.findPartnerByOwnerId(map);
		list.add(partner);
		
		map.clear();
		map.put("companyId", ownerId);
		map.put("ownerId", compId);
		map.put("isDelete", 0);
		map.put("relation", Partner.REALATION_CUSTOMER);
		partner = this.findPartnerByOwnerId(map);
		list.add(partner);
		
		return list;
	}
	
	public Map<String, Object> checkPartnerById(String partnerId) {
		Map<String, Object> mesMap = getPartnerByIdAndOwnerId(partnerId);
		
		Integer compId = (Integer) mesMap.get("companyId");
		if(compId == null) {
			mesMap.clear();
			mesMap.put("result", "error");
			return mesMap;
		}
		
		String compName = (String) mesMap.get("name");
		
		mesMap.clear();
		mesMap.put("ownerId", compId);
		mesMap.put("companyId", UserHolder.getCurrentSessionMessage().getCompanyId());
		mesMap.put("relation", Partner.REALATION_CUSTOMER);
		mesMap.put("isDelete", 0);
		Partner p = findPartnerByOwnerId(mesMap);
		
		mesMap.clear();
		if(p != null) {
			mesMap.put("result", "ok");
		} else {
			mesMap.put("result", "notExist");
			mesMap.put("compId", compId);
			mesMap.put("compName", compName);
		}
		
		return mesMap;
	}
	
	/**
	 * 检查业务伙伴
	 * 
	 * @author ycf
	 * 
	 * @param compId
	 * @return
	 */
	public Map<String, Object> checkPartner(Integer compId) {
		SessionMessage se = UserHolder.getCurrentSessionMessage();
		Integer ownerId = se.getCompanyId();
		
		Map<String, Object> map = new HashMap<String, Object>();
		
		//客户或供应商不能是自己
		if(ownerId.equals(compId)) {
			map.put("result", "ownerIdEqualsCompId");
			return map;
		}
		
		Company company = (Company) companyDao.getById(compId);
		//公司不存在
		if(company == null) {
			map.put("result", "companyIsNull");
			return map;
		}
		
		List<Partner> partners = getPartnerByCompIdAndOwnerId(compId);
		
		//不存在
		if(partners.get(0) == null) {
			map.put("result", "not_exist");
			return map;
		}
		
		//不存在
		if(partners.get(1) == null) {
			map.put("result", "otherAddPartner");
			return map;
		}
		
		//正确
		map.put("result", "go_on");
		map.put("partnerId", partners.get(0).getId().toString());
		return map;
	}
	
	
	public List<Partner> findPartnerByCondition(Map map){
		
		
		return this.getDao().findPartnerByCondition(map);
		
	}
	
	/**
	 * 根据情况增加或者修改业务伙伴
	 * 
	 * @author ycf
	 * 
	 * @param compId
	 * @param relation
	 * @return
	 */
//	public Map<String, Object> addPartnerOrUpdatePartner(Integer compId, String relation) {
//		SessionMessage se = UserHolder.getCurrentSessionMessage();
//		Integer ownerId = se.getCompanyId();
//		
//		Map<String, Object> map = new HashMap<String, Object>();
//		
//		Object obj = checkPartner(compId, relation);
//		if(obj instanceof Company) {
//			Company comp = (Company)obj;
//			Partner partner = new Partner();
//			setPartner(partner, comp, ownerId, relation);
//			getDao().create(partner);
//			map.put("result", "ok");
//			map.put("companyId", compId);
//			map.put("partnerId", partner.getId().toString());
//		} else if(obj instanceof Partner) {
//			Partner p = (Partner)obj;
//			p.setRelation(Partner.REALATION_BOTH);
//			getDao().update(p);
//			map.put("result", "ok");
//			map.put("companyId", compId);
//			map.put("partnerId", p.getId().toString());
//		} else if("-1".equals(obj)) {
//			map.put("result", "ownerIdEqualsCompId");
//		} else if("-2".equals(obj)) {
//			map.put("result", "companyIsNull");
//		} else {
//			map.put("result", "exist");
//		}
//		
//		return map;
//	}
	/**
	 * 检查双方业务伙伴
	 */
	public Map<String, Object> checkPartnerMes(Integer compId) {
		return checkPartner(compId);
	}
	
	public boolean updatePartner(Partner partner) {

		return this.getDao().updatePartner(partner);
	}
	
	private void setPartner(Partner partner, Company buyer, Integer ownerId, String relation) {
		partner.setOwnerId(ownerId);
		partner.setCompanyId(buyer.getId());
		partner.setName(buyer.getName());
		partner.setCode(buyer.getCode());
		partner.setAreaId(buyer.getAreaId());
		partner.setAddress(buyer.getAddress());
		partner.setBankCode(buyer.getBankCode());
		partner.setBankName(buyer.getBankName());
		partner.setBusiness(buyer.getBusiness());
		partner.setProvinceId(String.valueOf(buyer.getProvinceId()));
		partner.setProvince(buyer.getProvince());
		partner.setCity(buyer.getCity());
		partner.setCityId(String.valueOf(buyer.getCityId()));
		partner.setDistrict(buyer.getDistrict());
		partner.setContactor(buyer.getContactor());
		partner.setContactorIdentityCode(buyer.getContactorIdentityCode());
		partner.setEmail(buyer.getEmail());
		partner.setFax(buyer.getFax());
		partner.setInvoicAddress(buyer.getInvoicAddress());
		partner.setPyCode(buyer.getPyCode());
		partner.setQq(buyer.getQq());
		partner.setMsn(buyer.getMsn());
		partner.setSimpleName(buyer.getSimpleName());
		partner.setTaxCode(buyer.getTaxCode());
		partner.setTel(buyer.getTel());
		partner.setWeb(buyer.getWeb());
		partner.setRelation(relation);
	}
	public List<Partner> getListByCondition(Map map){
		return getDao().getPartnersByConditions(map);
	}
	public Partner getPartnerByCondition(Map map){
		List<Partner> list=this.getListByCondition(map);
		return list.size()==1?list.get(0):null;
	}
}